﻿using System;
using System.Reflection;

namespace ReflectStudy
{

    class Test {
        private int password=123456;
        public int age;
        public String name;
        public Boolean flag;

        public Test() {
            Console.WriteLine("无参构造函数");
        }

        public Test(int a,String b) {
            this.age = a;
            this.name = b;
            Console.WriteLine("2个参数的有参构造函数");
        }

        public Test(int a, String b, bool c) {
            Console.WriteLine("3个参数的有参构造函数");
        }

        public  void Display() {
            Console.WriteLine("password:"+this.password);
            Console.WriteLine("age:" + this.age);
            Console.WriteLine("name:"+this.name);
            Console.WriteLine("flag:"+this.flag);

        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test t = new Test();
            //获取Type(类对象信息，包含成员信息，函数信息等)
            Type type = t.GetType();//使用Object类继承来的方法进行获取
            Type type1 = typeof(Test);//使用操作符typeof获取类型信息(Type信息)
            Type type2 = Type.GetType("ReflectStudy.Test");//使用Type类中的静态方法进行获取
            Console.WriteLine(type);
            Console.WriteLine(type1);
            Console.WriteLine(type2);
            Console.WriteLine("==========================");

            //通过获取到的信息，来打印程序集
            Console.WriteLine(type.Assembly);
            Console.WriteLine("------");
            Console.WriteLine(type1.Assembly);
            Console.WriteLine("-------");
            Console.WriteLine(type2.Assembly);
            Console.WriteLine("==========================");

            //获取类中的公共成员(字段，函数(包括构造函数)等)
            MemberInfo[] memberInfos = type.GetMembers();
            for (int i = 0; i < memberInfos.Length; i++) {
                Console.WriteLine(memberInfos[i]);
            }
            Console.WriteLine("==========================");
            //获取公共成员变量
            //1.获取所有公共成员变量
            FieldInfo[] fieldInfos = type.GetFields();
            for (int i = 0; i < fieldInfos.Length; i++) {
                Console.WriteLine(fieldInfos[i]);
            }
            Console.WriteLine("==========================");
            //2.获取指定公共成员变量
            FieldInfo fieldInfo = type.GetField("age");
            FieldInfo fieldInfo1 = type1.GetField("name");
            Console.WriteLine(fieldInfo+"   "+fieldInfo1);
            Console.WriteLine("==========================");
            //通过反射来获取成员变量的值和修改成员变量的值
            Test test1 = new Test(20, "李华");
            Type type4 = test1.GetType();//获取类信息
            FieldInfo name1 = type4.GetField("name");//获取公共成员nama的信息
            FieldInfo age = type4.GetField("age");//获取公共成员age的信息
            Console.WriteLine(name1.GetValue(test1));//注意传入的参数是你要获取该字段信息的对象
            Console.WriteLine(age.GetValue(test1));//同上
            Console.WriteLine("修改后");
            name1.SetValue(test1, "蔡徐坤");
            age.SetValue(test1, 21);
            Console.WriteLine(name1.GetValue(test1));
            Console.WriteLine(age.GetValue(test1));
            Console.WriteLine("=========================");


            //获取公共构造函数
            //1.获取所有公共构造函数
            Test test3 = new Test(50, "白白");
            Type type3 = Type.GetType("ReflectStudy.Test");
            ConstructorInfo[] constructors = type3.GetConstructors();
            for (int i = 0; i < constructors.Length; i++) {
                Console.WriteLine(constructors[i]);
            }
            Console.WriteLine("============================");
            //获取指定构造函数并执行(下方其中Type[]数组就是构造函数参数类型(参数表Type数组))
            ConstructorInfo constructor = type3.GetConstructor(new Type[0]);//获取无参构造函数
            ConstructorInfo constructor1 = type3.GetConstructor(new Type[2] { typeof(int), typeof(String) });//获取2个参数的构造函数
            ConstructorInfo constructor2 = type3.GetConstructor(new Type[3] { typeof(int), typeof(String), typeof(bool) });//获取3个参数构造函数
            //使用获取到的构造函数进行实例化
            Test nullTest = constructor.Invoke(null) as Test;
            Test twoTest = constructor1.Invoke(new object[2] { 19, "李华" }) as Test;
            Test threeTest = constructor2.Invoke(new object[3] { 20, "坤坤", true }) as Test;
            nullTest.Display();
            twoTest.Display();
            threeTest.Display();
            Console.WriteLine("===============================");

            Console.WriteLine("=========================");
            //获取String类的成员函数
            //Type str=Type.GetType("")
            Type strTest = typeof(string);
            MethodInfo[] memberInfos1 = strTest.GetMethods();
            for (int i = 0; i < memberInfos.Length; i++) {
                Console.WriteLine(memberInfos1[i]);
            }
            Console.WriteLine("获取指定类方法");
            //获取类中的指定成员（参数一为函数名，参数二为参数类型数组(Type)）
            MethodInfo strSubstring = strTest.GetMethod("Substring",new Type[2] {typeof(int),typeof(int)});
            String test = "hello ikun";
            //调用指定类函数
            object index = strSubstring.Invoke(test, new object[2] { 1, 3 });
            Console.WriteLine(test+" 切割字符串结果为:"+index);

        }
        //static void F1() {
        //    Console.WriteLine("4");
        //}

        //static void F1(int a,string str="") { 
        
        //}
    }
}
